package recolhalixo;

import jadex.extension.envsupport.math.IVector2;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.HashMap;

public class BaseConhecimento {
	
	
	public static class Caixote {
		public double taxa;
		public long ult_actualizacao;
		public long ult_quant;
		public long capacidade;
		
		//public Caixote() {taxa=0;ult_actualizacao=0;ult_quant=-1;}
		public Caixote(long a,long q,long c) {
			taxa=0;
			ult_actualizacao=a;
			ult_quant=q;
			capacidade=c;}
	}
	
	private HashMap<IVector2,Caixote> dados;
	private PropertyChangeSupport pcs;
	private long tick;
	
	public BaseConhecimento() {
		dados = new HashMap<IVector2,Caixote>();
		pcs= new PropertyChangeSupport(this);
		tick=0;
	}
	
	public HashMap<IVector2, Caixote> getDados() {return dados;}
	public void setTick(long t) {
		if (t>tick) {
			long old = tick;
			tick=t;
			pcs.firePropertyChange("tick", old, tick);
		}
	}
	public long getTick() {return tick;}
	
	public void updateDados(IVector2 pos,Caixote c) {
		HashMap<IVector2, Caixote> old = (HashMap<IVector2, Caixote>) dados.clone();
		
		if (dados.containsKey(pos)) {
			Caixote old_data=dados.get(pos);
			if (old_data.ult_actualizacao<c.ult_actualizacao && old_data.ult_quant<c.ult_quant) {
				double newTaxa=(double)(c.ult_quant-old_data.ult_quant)/(double)(c.ult_actualizacao-old_data.ult_actualizacao);
				if (old_data.taxa==0) {old_data.taxa=newTaxa;}
				else {old_data.taxa=0.5*newTaxa+0.5*old_data.taxa;}
			}
			if (c.capacidade>old_data.capacidade) {old_data.capacidade=c.capacidade;}
			old_data.ult_quant=c.ult_quant;
			old_data.ult_actualizacao=c.ult_actualizacao;
		}
		else {dados.put(pos, c);}
		pcs.firePropertyChange("dados", old, dados);
	}
	
	public boolean isEmpty() {return dados.isEmpty();}
	
	public ArrayList<IVector2> getGoals(long t) {
		ArrayList <IVector2> results = new ArrayList<IVector2>();
		for (IVector2 vect:dados.keySet()) {
			// Caixote novo
			Caixote c = dados.get(vect);
			if ((c.taxa==0 || c.capacidade==0) && c.ult_actualizacao-t>3) {results.add(vect);}
			else if (
					(c.ult_quant+c.taxa*(t-c.ult_actualizacao))>=c.capacidade/2)
					{
					results.add(vect);}
		}
		return results;
	}
	
	public void addPropertyChangeListener(PropertyChangeListener listener) {
	    pcs.addPropertyChangeListener(listener);
	}
	public void removePropertyChangeListener(PropertyChangeListener listener) {
	    pcs.removePropertyChangeListener(listener);
	}

}
